import { globalStyle, GlobalStyleRule } from '@vanilla-extract/css';

/**
 * Make a color lighter or darker(lighter when system is light mode, darker when system is dark mode)
 * @param color Src color
 * @param value Brighten value, range is [0, 1], default is 0.1
 * @returns Jusified value
 */
export function brighten(color: string, value = 0.1): string {
	return `light-dark(hsl(from ${color} h s calc(l + ${value * 100})), hsl(from ${color} h s calc(l - ${value * 100})))`;
}

/**
 * Make a color lighter
 * @param color Src color
 * @param value Brighten value, range is [0, 1], default is 0.1
 * @returns Jusified value
 */
export function brightenAbs(color: string, value = 0.1): string {
	return `hsl(from ${color} h s calc(l + ${value * 100}))`;
}

/**
 * Make a color darker or lighter(darker when system is light mode, lighter when system is dark mode)
 * @param color Src color
 * @param value Darken value, range is [0, 1], default is 0.1
 * @returns Jusified value
 */
export function darken(color: string, value = 0.1): string {
	return `light-dark(hsl(from ${color} h s calc(l - ${value * 100})), hsl(from ${color} h s calc(l + ${value * 100})))`;
}

/**
 * Make a color darker
 * @param color Src color
 * @param value Darken value, range is [0, 1], default is 0.1
 * @returns Jusified value
 */
export function darkenAbs(color: string, value = 0.1): string {
	return `hsl(from ${color} h s calc(l - ${value * 100}))`;
}

/**
 * Support light and dark mode (fall back behavior)
 * @param selector selector of target, if want to apply to root, set it to ''
 * @param lightRule Light mode rule
 * @param darkRule Dark mode rule
 */
export function fallBackGlobalStyle(selector: string, lightRule: GlobalStyleRule, darkRule: GlobalStyleRule) {
	globalStyle(selector || ':root', {
		'@supports': {
			'not (color: light-dark(black, white))': {
				...lightRule,
				'@media': {
					'(prefers-color-scheme: dark)': darkRule,
				},
			},
		},
	});
	globalStyle(`:root.light${selector ? ' ' + selector : ''}`, {
		'@supports': {
			'not (color: light-dark(black, white))': lightRule,
		},
	});
	globalStyle(`:root.dark${selector ? ' ' + selector : ''}`, {
		'@supports': {
			'not (color: light-dark(black, white))': darkRule,
		},
	});
}

/**
 * Use media query to support light and dark mode. The framework does not use the CSS light-dark() function
 * @param selector selector of target, if want to apply to root, set it to ''
 * @param lightRule Light mode rule
 * @param darkRule Dark mode rule
 */
export function lightDark(selector: string, lightRule: GlobalStyleRule, darkRule: GlobalStyleRule) {
	globalStyle(selector, {
		...lightRule,
		'@media': {
			'(prefers-color-scheme: dark)': darkRule,
		},
	});
	globalStyle(':root.light ' + selector, lightRule);
	globalStyle(':root.dark ' + selector, darkRule);
}

export type HSLInfo = {
	/**
	 * 色相：0-360度
	 */
	hue: number;
	/**
	 * 饱和度：0-100%
	 */
	saturation: number;
	/**
	 * 亮度：0-100%
	 */
	lightness: number;
	/**
	 * 透明度：0-1（默认1）
	 */
	alpha: number;
};

/**
 * 解析HSL格式字符串，返回HSL对象
 * @param hslString HSL格式字符串，支持hsl()和hsla()格式，例如：hsl(213, 73%, 50%) 或 hsla(213, 73%, 50%, 0.5)
 * @returns HSL 对象，包含色相、饱和度、亮度和透明度，解析失败时返回默认值：透明
 */
export function parseHSL(hslString: string): HSLInfo {
	// 支持hsl()和hsla()格式，兼容空格和透明度
	const hslRegex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(?:,\s*([\d.]+)\s*)?\)/i;
	const match = hslString.match(hslRegex);
	if (!match) return { hue: 0, saturation: 0, lightness: 0, alpha: 0 };
	const [, hue, saturation, lightness, alpha] = match;
	return {
		hue: parseInt(hue, 10), // 色相：0-360度
		saturation: parseInt(saturation, 10), // 饱和度：0-100%
		lightness: parseInt(lightness, 10), // 亮度：0-100%
		alpha: alpha ? parseFloat(alpha) : 1, // 透明度：0-1（默认1）
	};
}

/**
 * 把 HSL 对象转换成 CSS HSL 格式字符串
 * @param hsl HSL对象
 * @returns 字符串，例如：hsl(213, 73%, 50%) 或 hsla(213, 73%, 50%, 0.5)
 */
export function toHSL(hsl: HSLInfo): string {
	return `hsl(${hsl.hue}, ${hsl.saturation}%, ${hsl.lightness}%, ${hsl.alpha})`;
}

/**
 * 修改HSL颜色的亮度
 * @param hslColor HSL 格式字符串，例如：hsl(213, 73%, 50%) 或 hsla(213, 73%, 50%, 0.5)
 * @param modifyValue 亮度修改值，范围是 [-1, 1]，负数表示降低亮度，正数表示增加亮度
 * @returns 修改后的 HSL 格式字符串
 */
export function modifyHSLColorLightness(hslColor: string, modifyValue: number): string {
	const hsl = parseHSL(hslColor);
	hsl.lightness = Math.max(0, Math.min(100, hsl.lightness + modifyValue * 100));
	return toHSL(hsl);
}
